
#ifndef _M_APP_GMUX0710_H_
#define _M_APP_GMUX0710_H_

#define GMUX_INIT_CMD    "AT+CMUX=0\r"

#define GMUX_CTX_CHL     0
#define GMUX_CTX_CHL_ADDR   0x03

#define GMUX_CMD_CHL     1
#define GMUX_CMD_CHL_ADDR   0x07

#define GMUX_DATA_CHL    2
#define GMUX_DATA_CHL_ADDR  0x0B

#define GMUX_BASIC_MODE         0
#define GMUX_BASIC_MODE_FLAG    0xF9
#define GMUX_BASIC_MODE_DATA_SIZE 127

#define GMUX_ADVANCED_MODE      1
#define GMUX_ADVANCED_MODE_FLAG 0x7E
#define GMUX_ADVANCED_MODE_DATA_SIZE

#define GMUX_ADDR_EA      1
#define GMUX_ADDR_CR      2
#define GMUX_ADDR_CR_CIR  1
#define GMUX_ADDR_CR_RRI  1
#define GMUX_ADDR_CR_CRI  0
#define GMUX_ADDR_CR_RIR  0

#define GMUX_SET_FLAG(addr, flag)       (addr = flag)

#define GMUX_SET_ADDR_EA(addr, bit)       ((addr & 0xFE) | (bit<<0))
#define GMUX_SET_ADDR_CR(addr, bit)       ((addr & 0xFD) | (bit<<1))
#define GMUX_SET_ADDR_DLCI(addr, channel) ((addr & 0x03) | (((0x3F & channel) << 2))
#define GMUX_SET_ADDR(addr, channel) (addr = channel)

#define GMUX_SET_CTX(addr, flag)        (addr = flag)

#define GMUX_SET_LEN(addr, len)         ((addr & 0x01) | ((GMUX_BASIC_MODE_DATA_SIZE & len) << 1))

#define GMUX_SET_FCS(addr, flag)        (addr = flag)

#define GMUX_CTX_SABM   0x3F /* Set Asynchronous Balanced Mode (command) */
#define GMUX_CTX_UA   	0x73 /* Unnumbered Acknowledgement (respond) */
#define GMUX_CTX_DM     0x0F /* Disconnected Mode (respond) */
#define GMUX_CTX_DISC   0x43 /* Disconnect (peer command) */
#define GMUX_CTX_UIH    0xEF /* Unnumbered Information with header Check (respond) */
#define GMUX_CTX_UI     0x03 /* Unnumbered Information (respond) */

enum GMUX_RET{

  GMUX_BUSY = 4,
  GMUX_CONTINUE = 3,
  GMUX_CMD_ERR = 2,
  GMUX_CMD_OK = 1,
  GMUX_OK = 0,
  GMUX_ERR = -1,
  GMUX_TIMEOUT = -2,
};

typedef int (*fpPutChar)(unsigned char ucCh);
typedef int (*fpGetChar)(void);
typedef int (*fpMuxTick)(void);

typedef struct GSM0710_Basic_Frame_t{
  unsigned char ucFlag;
  unsigned char ucChannel;
  unsigned char ucControl;
  unsigned char data_length;
  unsigned char *pucData;
  unsigned char ucCrc;
}GSM0710_Basic_Frame;

typedef struct GSM0710_Advanced_Frame_t{
  unsigned char ucFlag;
  unsigned char ucChannel;
  unsigned char ucControl;
  unsigned char *pucData;
  unsigned char ucCrc;
}GSM0710_Advanced_Frame;

typedef struct GmuxCtx_t{
  unsigned char ucModel;
  unsigned char ucChlCount;
  fpPutChar fPutChar;
  fpGetChar fGetChar;
  fpMuxTick fTick;
  
}GmuxCtx;

void gmux_main_proc(GmuxCtx *ctx);

int gmux_init(GmuxCtx *ctx, unsigned char ucModel, fpPutChar fPutChar, fpGetChar fGetChar, fpMuxTick fTick);
int gmux_basic_init(GmuxCtx *ctx, unsigned int uiTimeout);
int gmux_put_ch(GmuxCtx *ctx, unsigned char ucChannel, unsigned char ucCh);
int gmux_get_ch(GmuxCtx *ctx, unsigned char ucChannel);
int gmux_send(GmuxCtx *ctx, unsigned char ucChannel, unsigned char *pucData, unsigned char ucDLen);
int gmux_recv(GmuxCtx *ctx, unsigned char ucChannel, unsigned char *pucBuff, unsigned int ucSize);

#endif

